package com.jic.manager.controller.manage.sys;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jic.common.base.vo.AdminOperate;
import com.jic.common.base.vo.Page;
import com.jic.common.base.vo.PageResult;
import com.jic.common.base.vo.RestResult;
import com.jic.common.redis.RedisClientTemplate;
import com.jic.enums.RedisKey;
import com.jic.manager.common.util.BeanUtil;
import com.jic.manager.entity.*;
import com.jic.manager.request.SysRoleMenuRequest;
import com.jic.manager.request.SysRoleRequest;
import com.jic.manager.response.SysMenuResponse;
import com.jic.manager.response.SysRoleInfoMenuResponse;
import com.jic.manager.response.SysRoleMenuResponse;
import com.jic.manager.response.SysRoleResponse;
import com.jic.manager.service.*;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("sysRole")
public class SysRoleController {

    @Resource
    private RedisClientTemplate redisClientTemplate;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private SysMenuService sysMenuService;
    @Resource
    private SysRoleMenuService sysRoleMenuService;
    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysRoleLogService sysRoleLogService;

    @Resource
    private SysRoleMenuVerifyService sysRoleMenuVerifyService;

    @PostMapping("queryPageSysRole")
    public RestResult<PageResult<SysRole>> queryPageSysRole(@RequestBody SysRoleRequest sysRoleVo){
        RestResult<PageResult<SysRole>> pageResultRestResult = new RestResult<>();
        try{
            pageResultRestResult = sysRoleService.queryPageList(sysRoleVo);
        }catch (Exception e){
            e.printStackTrace();
            pageResultRestResult.setCode("9999");
            pageResultRestResult.setMsg(e.getLocalizedMessage());
        }
        return pageResultRestResult;
    }

    @PostMapping("editSysRole")
    public RestResult<String> editSysRole(@RequestBody SysRoleRequest sysRoleRequest){
        try{
            SysRole sysRole = new SysRole();
            BeanUtils.copyProperties(sysRoleRequest,sysRole);
           if(sysRoleRequest.getId() == null || sysRoleRequest.getId() == 0){
               //新增
               sysRoleService.insert(sysRole);
           } else{
               sysRoleService.update(sysRole);
           }
           return RestResult.success("成功");
        }catch (Exception e){
            e.printStackTrace();
            return RestResult.error("9999",e.getLocalizedMessage());
        }
    }

    @PostMapping("deleteSysRole")
    public RestResult<Boolean> deleteSysRole(@RequestBody SysRoleRequest sysRoleRequest){
        try{
           boolean falg =  sysRoleService.delete(sysRoleRequest);
            return RestResult.success(falg);
        }catch (Exception e){
            e.printStackTrace();
            return RestResult.error("9999",e.getLocalizedMessage());
        }
    }

    @PostMapping(value = "saveRoleMenus")
    public RestResult<String>  saveRoleMenus(@RequestBody SysRoleRequest sysRoleRequest){
        try {
            String roleMenusStr = sysRoleRequest.getRoleMenus();
            List<SysRoleMenuRequest> roleMenus = (List<SysRoleMenuRequest>) JSONUtils.parse(roleMenusStr);
            Long roleId = sysRoleRequest.getRoleId();
            sysRoleMenuService.deleteByRoleId(roleId);
            //新增
            sysRoleMenuService.insertList(roleMenus);
            //新增日志
            sysRoleLogService.insert(new SysRoleLog(){{
                setRoleId(roleId);
                setContent(JSONArray.toJSONString(roleMenus));
                setCreator(sysRoleRequest.getCreator());
                setCreatorName(sysRoleRequest.getCreatorName());
                setCreateTime(new Date());
            }});
            return RestResult.success("成功");
        }catch (Exception e){
            e.printStackTrace();
            return RestResult.error("9999",e.getLocalizedMessage());
        }
    }


    @PostMapping("queryMenusByRoleId")
    public RestResult<List<SysMenu>> queryMenusByRoleId(@RequestBody SysRoleMenu sysRoleMenu){
        try {
            //根据roleid查询所有的菜单
            SysRole sysRole = sysRoleService.queryByPrimaryKey(sysRoleMenu.getRoleid());
            List<SysRoleMenu> sysRoleMenus = new ArrayList<>();
            if(sysRole.getStatus()!=3){
                SysRoleMenuVerify  sysRoleMenuVerify = sysRoleMenuVerifyService.getSysRoleMenuVerifyByRoleId(sysRole.getId());
                JSONObject map = JSONObject.parseObject(sysRoleMenuVerify.getModifyText());
                List<SysRoleMenu> roleMenusList = JSONObject.parseArray(map.get("roleMenusList").toString(), SysRoleMenu.class);
                sysRoleMenus = roleMenusList;
            }else{
                sysRoleMenus = sysRoleMenuService.query(sysRoleMenu);
            }
            List<SysMenu> sysMenus = new ArrayList<>();
            sysRoleMenus.forEach(sysRoleMenu1 -> {
                //查询菜单
                if("1".equals(sysRoleMenu1.getStatus())){
                    return;
                }
                SysMenu sysMenu = sysMenuService.queryByPrimaryKey(sysRoleMenu1.getMenuid());
                sysMenus.add(sysMenu);
            });
            return RestResult.success(sysMenus);
        }catch (Exception e){
            e.printStackTrace();
            return RestResult.error("9999",e.getLocalizedMessage());
        }
    }


    @PostMapping("findMenuTree")
    public RestResult<SysRoleMenuResponse> findMenuTree(@RequestBody SysRoleMenuRequest sysRoleMenu){
        try {
            List<SysMenu> sysMenus = new ArrayList<>();

            SysRoleMenuRequest parm = new SysRoleMenuRequest();
            if (sysRoleMenu.getRoleid() != null){
                //查询所有菜单
                String type = sysRoleMenu.getType();
                sysMenus = sysMenuService.query(new SysMenu() {{
                    setOwningPlatform(type);
                    setDeleteFlag(0);
                }});
            }else{
                //获取登录人token 查询用户
                String userStr = redisClientTemplate.get(sysRoleMenu.getToken());
                if(StringUtils.isEmpty(userStr)){
                    return RestResult.error("4000","登录失效");
                }
                //判断当前登陆人是否存在菜单
                String menuList = redisClientTemplate.get(RedisKey.ADMIN_MENU_LIST_.getName() + sysRoleMenu.getToken());
                if(StringUtils.isNotEmpty(menuList)){
                    SysRoleMenuResponse sysRoleMenuResponse = JSONObject.parseObject(menuList, SysRoleMenuResponse.class);
                    if (sysRoleMenuResponse!=null){
                       return RestResult.success(sysRoleMenuResponse);
                    }
                }
                SysUser sysUser = JSONArray.parseObject(userStr,SysUser.class);
                SysUser sysUser1 = sysUserService.queryByPrimaryKey(sysUser.getId());
                if(sysUser1 == null) {
                    throw new Exception("用户不存在");
                }
                parm.setRoleid(sysUser1.getRoleid());
                parm.setUserId(sysUser1.getId());
                List<SysMenu> finalSysMenus = sysMenuService.getRoleMenuListByRoleid(parm);
                sysMenus = finalSysMenus;
            }
            List<SysMenuResponse> resultList = sysMenus.stream().filter(x -> { return x != null;})
                    .filter(x -> { return StringUtils.isEmpty(x.getPid()) || x.getPid().equals("0");})
                    .map(x ->{
                        SysMenuResponse sysMenuResponse = BeanUtil.copy(x, SysMenuResponse.class);
                        sysMenuResponse.setLevel(0);
                        return sysMenuResponse;
                    }).collect(Collectors.toList());
            findChildren(resultList, sysMenus,1);
            resultList.sort((o1, o2) -> o1.getSort().compareTo(o2.getSort()));
            List<SysMenu> roleList = sysMenuService.findPermissions(parm);
            Set<String> perms = roleList.stream().filter(x ->{ return StringUtils.isNotEmpty(x.getPerms());}).map(SysMenu::getPerms).collect(Collectors.toSet());
            SysRoleMenuResponse sysRoleMenuResponse = new SysRoleMenuResponse();
            sysRoleMenuResponse.setMenuList(resultList);
            sysRoleMenuResponse.setPermsList(perms);
            if (sysRoleMenu.getRoleid() == null){
                redisClientTemplate.set(RedisKey.ADMIN_MENU_LIST_.getName()+sysRoleMenu.getToken(), JSONObject.toJSONString(sysRoleMenuResponse));
            }
            return RestResult.success(sysRoleMenuResponse);
        }catch (Exception e){
            e.printStackTrace();
            return RestResult.error("9999",e.getLocalizedMessage());
        }
    }


    /**
     * 判断当前权限是否添加过
     *
     * @param sysMenus
     * @param sysMenu
     * @return
     */
    private boolean exists(List<SysMenuResponse> sysMenus, SysMenu sysMenu) {
        boolean exist = false;
        for (SysMenuResponse menu : sysMenus) {
            if (menu.getId() == sysMenu.getId()) {
                exist = true;
            }
        }
        return exist;
    }

    private void findChildren(List<SysMenuResponse> SysMenus, List<SysMenu> menus,int type) {
        for (SysMenuResponse SysMenu : SysMenus) {
            List<SysMenuResponse> children = new ArrayList<>();
            for (SysMenu menu : menus) {
                if (menu == null){
                    continue;
                }
                if ("2".equals(menu.getTypes()) && type == 1) {
                    // 如果是获取类型不需要按钮，且菜单类型是按钮的，直接过滤掉
                    continue;
                }
                if (SysMenu.getId() != null && String.valueOf(SysMenu.getId()).equals(menu.getPid())) {
                    SysMenuResponse sysMenuResponse = new SysMenuResponse();
                    BeanUtils.copyProperties(menu,sysMenuResponse);
                    sysMenuResponse.setParentName(SysMenu.getName());
                    sysMenuResponse.setLevel(SysMenu.getLevel()+1);
                    if (!exists(children, menu)) {
                        children.add(sysMenuResponse);
                    }
                }
            }
            SysMenu.setChildren(children);
            children.sort((o1, o2) -> o1.getSort().compareTo(o2.getSort()));
            findChildren(children, menus,type);
        }
    }


    /**
     * 获取菜单列表
     * @param sysRoleMenu
     * @return
     */
    @PostMapping("findMenuTreeKas")
    public RestResult<List<SysMenuResponse>> findMenuTreeKas(@RequestBody SysRoleMenuRequest sysRoleMenu){
        try {
            List<SysMenu> sysMenus = new ArrayList<>();
            //查询所有菜单
            String type = sysRoleMenu.getType();
            sysMenus = sysMenuService.query(new SysMenu() {{
                setOwningPlatform(type);
                setDeleteFlag(0);
            }});
            List<SysMenuResponse> resultList = new ArrayList<>();
            for (SysMenu menu : sysMenus) {
                if(menu == null){
                    continue;
                }
                SysMenuResponse sysMenuResponse = new SysMenuResponse();
                BeanUtils.copyProperties(menu,sysMenuResponse);
                if (StringUtils.isEmpty(sysMenuResponse.getPid()) || sysMenuResponse.getPid().equals("0")) {
                    sysMenuResponse.setLevel(0);
                    if (!exists(resultList, menu) && menu.getDeleteFlag().equals(0)) {
                        resultList.add(sysMenuResponse);
                    }
                }
            }
            findChildren(resultList, sysMenus,2);
            resultList.sort((o1, o2) -> o1.getSort().compareTo(o2.getSort()));
            return RestResult.success(resultList);
        }catch (Exception e){
            e.printStackTrace();
            return RestResult.error("9999",e.getLocalizedMessage());
        }
    }

    /**
     * 角色新增编辑
     * @param sysRoleRequest
     * @return
     */
    @PostMapping("saveSysRole")
    public RestResult<String> saveSysRole(@RequestBody SysRoleRequest sysRoleRequest){
        try{
            sysRoleService.saveSysRole(sysRoleRequest);
            return RestResult.success("成功");
        }catch (Exception e){
            e.printStackTrace();
            return RestResult.error("9999",e.getLocalizedMessage());
        }
    }

    @ApiOperation("根据deptId查询角色列表")
    @PostMapping("/queryRoleListByDeptId")
    public RestResult<List<SysRole>> queryRoleListByDeptId(@RequestBody SysRole sysRole){
        return RestResult.success(sysRoleService.query(sysRole));
    }

    /**
     * 获取角色数据
     * @param sysRoleRequest
     * @return
     */
    @PostMapping("getSysRoleInfo")
    public RestResult<SysRoleInfoMenuResponse> getSysRoleInfo(@RequestBody SysRoleRequest sysRoleRequest){
        try{
            SysRoleInfoMenuResponse sysRoleInfoMenu = sysRoleService.getSysRoleInfo(sysRoleRequest);
            return RestResult.success(sysRoleInfoMenu);
        }catch (Exception e){
            e.printStackTrace();
            return RestResult.error("9999",e.getLocalizedMessage());
        }
    }


    /**
     * 获取角色数据
     * @param sysRoleRequest
     * @return
     */
    @PostMapping("getRoleInfo")
    public RestResult<SysRole> getRoleInfo(@RequestBody SysRoleRequest sysRoleRequest){
        try{
            SysRole sysRole = sysRoleService.queryByPrimaryKey(sysRoleRequest.getId());
            return RestResult.success(sysRole);
        }catch (Exception e){
            e.printStackTrace();
            return RestResult.error("9999",e.getLocalizedMessage());
        }
    }


    /**
     * 提交审核
     * @param sysRoleRequest
     * @return
     */
    @PostMapping("submitReview")
    public RestResult<Boolean> submitReview(@RequestBody SysRoleRequest sysRoleRequest){
        try{
            SysRole sysRole = BeanUtil.copy(sysRoleRequest, SysRole.class);
            Boolean flag = sysRoleService.submitReview(sysRole);
            return RestResult.success(flag);
        }catch (Exception e){
            log.error("SysRole submitReview error：",e);
            return RestResult.error("9999","系统异常，提交审核失败");
        }
    }

    /**
     * 批量提交审核
     * @param sysRoleRequest
     * @return
     */
    @PostMapping("batchSubmitReview")
    public RestResult<Boolean> batchSubmitReview(@RequestBody SysRoleRequest sysRoleRequest){
        try{
            Boolean flag = sysRoleService.batchSubmitReview(sysRoleRequest);
            return RestResult.success(flag);
        }catch (Exception e){
            log.error("SysRole submitReview error：",e);
            return RestResult.error("9999","系统异常，批量提交审核失败");
        }
    }

    /**
     * 撤销提交
     * @param sysRoleRequest
     * @return
     */
    @PostMapping("revokeReview")
    public RestResult<Boolean> revokeReview(@RequestBody SysRoleRequest sysRoleRequest){
        try{
            SysRole sysRole = BeanUtil.copy(sysRoleRequest, SysRole.class);
            Boolean flag = sysRoleService.revokeReview(sysRole);
            return RestResult.success(flag);
        }catch (Exception e){
            log.error("SysRole submitReview error：",e);
            return RestResult.error("9999","系统异常，撤销提交失败");
        }
    }

    /**
     * 审核角色
     * @param sysRoleRequest
     * @return
     */
    @PostMapping("roleReview")
    public RestResult<Boolean> roleReview(@RequestBody SysRoleRequest sysRoleRequest){
        try{
            SysRole sysRole = BeanUtil.copy(sysRoleRequest, SysRole.class);
            Boolean flag = sysRoleService.roleReview(sysRole);
            return RestResult.success(flag);
        }catch (Exception e){
            log.error("SysRole submitReview error：",e);
            return RestResult.error("9999","系统异常，审核失败");
        }
    }

    /**
     * 批量提交审核
     * @param sysRoleRequest
     * @return
     */
    @PostMapping("batchRoleReview")
    public RestResult<Boolean> batchRoleReview(@RequestBody SysRoleRequest sysRoleRequest){
        try{
            Boolean flag = sysRoleService.batchRoleReview(sysRoleRequest);
            return RestResult.success(flag);
        }catch (Exception e){
            log.error("SysRole submitReview error：",e);
            return RestResult.error("9999","系统异常，批量审核失败");
        }
    }

}
